package org.xjb.cordova.amaplocation;

import android.location.Location;
import android.os.Bundle;

import java.util.HashMap;
import java.util.Map;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.location.LocationManagerProxy;
import com.amap.api.location.LocationProviderProxy;

public class MyAMapLocation extends CordovaPlugin {

    private static final String STOP_ACTION = "stop";
    private static final String GET_ACTION = "getCurrentPosition";
    private boolean enableHighAccuracy;
    private String coorType;
    private int timeout;
    private int scanSpan;
    private boolean isNeedAddress;

    private CallbackContext callbackContext;
    private LocationManagerProxy mLocationManagerProxy;
    private AMapLocationListener mListener = new MyLocationListener();

    private static final Map<Integer, String> ERROR_MESSAGE_MAP = new HashMap<Integer, String>();

    private static final String DEFAULT_ERROR_MESSAGE = "定位失败";

    static {
        ERROR_MESSAGE_MAP.put(21, "IO 操作异常");
        ERROR_MESSAGE_MAP.put(22, "连接异常");
        ERROR_MESSAGE_MAP.put(23, "连接超时");
        ERROR_MESSAGE_MAP.put(24, "无效的参数");
        ERROR_MESSAGE_MAP.put(25, "空指针异常");
        ERROR_MESSAGE_MAP.put(26, "url 异常");
        ERROR_MESSAGE_MAP.put(27, "未知主机");
        ERROR_MESSAGE_MAP.put(28, "连接服务器失败");
        ERROR_MESSAGE_MAP.put(29, "通信协议解析错误");
        ERROR_MESSAGE_MAP.put(30, "http 连接失败");
        ERROR_MESSAGE_MAP.put(31, "未知的错误");
        ERROR_MESSAGE_MAP.put(32, "key鉴权验证失败，请检查key绑定的sha1值、packageName与apk是否对应");
        ERROR_MESSAGE_MAP.put(33, "没有获取到定位权限，导致定位失败，请告知用户授予定位权限");
        ERROR_MESSAGE_MAP.put(34, "无法获取城市信息");
        ERROR_MESSAGE_MAP.put(35, "当前IP请求次数超过配额");
        ERROR_MESSAGE_MAP.put(36, "无法进行H5辅助定位");
    };

    public String getErrorMessage(int locationType) {
        String result = ERROR_MESSAGE_MAP.get(locationType);
        if (result == null) {
            result = DEFAULT_ERROR_MESSAGE;
        }
        return result;
    }

    @Override
    public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {
        this.callbackContext = callbackContext;
        if (GET_ACTION.equals(action)) {
            this.enableHighAccuracy = args.getBoolean(0);
            this.coorType = args.getString(1);
            this.timeout = args.getInt(2);
            this.scanSpan = args.getInt(3);
            this.isNeedAddress = args.getBoolean(4);

            cordova.getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (mLocationManagerProxy == null) {
                        mLocationManagerProxy = LocationManagerProxy.getInstance(cordova.getActivity());
                    } else {
                        //mLocationManagerProxy.removeUpdates(this);
                    }

                    mLocationManagerProxy.setGpsEnable(enableHighAccuracy);
                    mLocationManagerProxy.requestLocationData(LocationProviderProxy.AMapNetwork, -1, 15, mListener);
                }

            });
            return true;
        } else if (STOP_ACTION.equals(action)) {

            callbackContext.success(200);
            return true;
        } else {
            callbackContext.error(PluginResult.Status.INVALID_ACTION.toString());
        }

        return false;
    }

    public class MyLocationListener implements AMapLocationListener {

        @Override
        public void onLocationChanged(AMapLocation amapLocation) {
            if (amapLocation == null)
                return;

            if (amapLocation.getAMapException().getErrorCode() != 0) {
                callbackContext.error(amapLocation.getAMapException().getErrorMessage());
            } else {
                try {
                    JSONObject jsonObj = new JSONObject();
                    JSONObject coords = new JSONObject();
                    coords.put("latitude", amapLocation.getLatitude());
                    coords.put("longitude", amapLocation.getLongitude());
                    coords.put("radius", amapLocation.getAccuracy());

                    jsonObj.put("coords", coords);
                    jsonObj.put("code", 0);

                    callbackContext.success(jsonObj);
                } catch (JSONException e) {
                    callbackContext.error(e.getMessage());
                }
            }
        }

        @Override
        public void onLocationChanged(Location location) {

        }

        @Override
        public void onStatusChanged(String s, int i, Bundle bundle) {

        }

        @Override
        public void onProviderEnabled(String s) {

        }

        @Override
        public void onProviderDisabled(String s) {

        }
    }

    @Override
    public void onDestroy() {
        if (mLocationManagerProxy != null) {
            //mLocationManagerProxy.removeUpdates(mListener);
            mLocationManagerProxy.destroy();
        }
        mListener = null;
        mLocationManagerProxy = null;
        super.onDestroy();
    }

    public CallbackContext getCallbackContext() {
        return callbackContext;
    }

    public void setCallbackContext(CallbackContext callbackContext) {
        this.callbackContext = callbackContext;
    }
}